package learm.pers.studygitlab.code.service.impl;


import com.jayway.jsonpath.internal.Utils;
import learm.pers.studygitlab.code.entity.GitGroups;
import learm.pers.studygitlab.code.entity.GitPrivateToken;
import learm.pers.studygitlab.code.entity.GitProject;
import learm.pers.studygitlab.code.entity.GitUser;
import learm.pers.studygitlab.code.service.CodeService;
import learm.pers.studygitlab.code.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName: CodeServiceImpl
 * @Description:
 * @Author: fangqing
 * @Date: 2021/6/28
 */
@Service
public class CodeServiceImpl implements CodeService {

    @Resource
    RestTemplate restTemplate;

    @Value("${gitlab.url}")
    private String GITLAB_URL;

    @Value("${gitlab.token}")
    private String GITLAB_PRIVATE_TOKEN;

    /** *********************** start 用户 ***************************** **/
    /**
     * 创建用户（只有管理员才能进行创建）
     * @param gitUserVo
     * @return
     */
    @Override
    public String createUser(GitUserVo gitUserVo) {
        try{
            String url = GITLAB_URL + "/api/v4/users";
            // 封装参数
            MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
            paramMap.add("name", gitUserVo.getName());
            paramMap.add("username",gitUserVo.getUsername());
            paramMap.add("password",gitUserVo.getPassword());
            paramMap.add("email",gitUserVo.getEmail());
            paramMap.add("can_create_group",gitUserVo.getCan_create_group());
            paramMap.add("skip_confirmation",gitUserVo.getSkip_confirmation());

            HttpHeaders headers = new HttpHeaders();
            headers.set("PRIVATE-TOKEN",GITLAB_PRIVATE_TOKEN);
            HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(paramMap, headers);

            // 使用postForObject请求接口
            GitUserVo gitUserVo1 = restTemplate.postForObject(url, httpEntity, GitUserVo.class);

            //将返回的结果添加到本地数据库
            if(gitUserVo1!=null && !"".equals(gitUserVo1)){
                //LoginUser loginUser = UserAuthenticationMsg.getLoginUser();
                //GitUser gitUser = getGitUser(loginUser, gitUserVo1);
                //gitUser.setPassword(gitUserVo.getPassword()).setProjectUuid(gitUserVo.getProjectUuid());
                //codeMapper.createUser(gitUser);
            }
            return "1";
        }catch (Exception e){
            e.printStackTrace();
            System.out.println(e.getMessage());
            return "2";
        }

    }
    /**
     * 获取指定用户
     * @param userId 用户id
     * @return
     */
    public GitUserVo findUser(Long userId,String flag) {
        try{
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Map<String, Object> uriVariables = new HashMap<>();
            String url = GITLAB_URL + "/api/v4/users/{userId}?private_token={privateToken}";
            uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
            uriVariables.put("userId", userId);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity entity = new HttpEntity<>(headers);
            ParameterizedTypeReference<GitUserVo> responseType = new ParameterizedTypeReference<GitUserVo>() {};
            ResponseEntity<GitUserVo> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
            if (HttpStatus.OK == responseEntity.getStatusCode()) {
                GitUserVo userVo = responseEntity.getBody();
                userVo.setCreatedTime(formatter.format(userVo.getCreatedAt())).setConfirmedTime(formatter.format(userVo.getConfirmedAt()));
                return userVo;
            }
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return null;
    }
    /**
     * 编辑用户（只有管理员才能进行创建）
     * @param gitUserVo
     * @return
     */
    @Override
    public String editUser(GitUserVo gitUserVo) {
        try{
            String url = GITLAB_URL + "/api/v4/users/"+gitUserVo.getId()+"?private_token="+GITLAB_PRIVATE_TOKEN;
            // 封装参数
            MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
            if(!"".equals(gitUserVo.getName()) && gitUserVo.getName()!=null){
                paramMap.add("name", gitUserVo.getName());
            }if(!"".equals(gitUserVo.getUsername()) && gitUserVo.getUsername()!=null){
                paramMap.add("username",gitUserVo.getUsername());
            }if(!"".equals(gitUserVo.getPassword()) && gitUserVo.getPassword()!=null){
                paramMap.add("password",gitUserVo.getPassword());
            }if(!"".equals(gitUserVo.getEmail()) && gitUserVo.getEmail()!=null){
                paramMap.add("email",gitUserVo.getEmail());
            }
            paramMap.add("can_create_group",gitUserVo.getCan_create_group());
            paramMap.add("skip_reconfirmation",gitUserVo.getSkip_confirmation());
            //设置请求头
            HttpHeaders headers = new HttpHeaders();
            HttpEntity httpEntity = new HttpEntity<>(paramMap, headers);
            ResponseEntity<GitUserVo> resEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, GitUserVo.class);

            if (HttpStatus.OK == resEntity.getStatusCode()) {
                GitUserVo body = resEntity.getBody();
                if(body!=null){
                    body.setPassword(gitUserVo.getPassword());
                    //修改本地数据库
                    //int i = codeMapper.editUser(body);
                    if(1>0){
                        return "1";
                    }
                    return "2";
                }
            }
        } catch (Exception e){
            e.printStackTrace();
            return "2";
        }
        return "2";
    }
    /**
     * 删除用户（只有管理员才能进行）
     * @param userId
     * @param project_uuid
     * @return
     */
    @Override
    public String deleteUser(Long userId, String project_uuid) {
        try{
            //1、先查询是否存在，不存在就不进行远程调用删除
            GitUserVo user = findUser(userId, "1");
            if(user!=null){
                Map<String, Object> uriVariables = new HashMap<>();
                String url = GITLAB_URL + "/api/v4/users/{userId}?private_token={privateToken}";
                uriVariables.put("userId", userId);
                uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
                ///2、先删除gitLab代码库上面的
                restTemplate.delete(url,uriVariables);
            }
            //3、删除本地数据库的记录
            //codeMapper.deleteUser(userId,project_uuid);
            return "1";
        } catch (Exception e){
            e.printStackTrace();
            return "2";
        }
    }

    /**
     * 创建用户个人令牌
     * @param gitPrivateTokenVo
     * @return
     */
    @Override
    public String createUserPrivateToken(GitPrivateTokenVo gitPrivateTokenVo) {
        try{
            String url = GITLAB_URL + "/api/v4/users/"+gitPrivateTokenVo.getUser_id()+"/personal_access_tokens";
            // 封装参数
            MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
            paramMap.add("name", gitPrivateTokenVo.getName());
            paramMap.add("expires_at",gitPrivateTokenVo.getExpires_at());
            String[] scopes = gitPrivateTokenVo.getScopes();
            StringBuffer sb = new StringBuffer();
            for(int i = 0; i < scopes.length; i++){
                sb. append(scopes[i]+",");
            }
            String ri = sb.toString().substring(0, sb.toString().length() - 1);
            paramMap.add("scopes[]",ri);

            HttpHeaders headers = new HttpHeaders();
            headers.set("PRIVATE-TOKEN",GITLAB_PRIVATE_TOKEN);
            HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(paramMap, headers);
            // 使用postForObject请求接口
            GitPrivateTokenVo gitPrivateTokenVo1 = restTemplate.postForObject(url, httpEntity, GitPrivateTokenVo.class);

            //将创建后的令牌存到本地数据库
            //if(gitPrivateTokenVo1!=null && !"".equals(gitPrivateTokenVo1)){
                //GitPrivateToken gitPrivateToken = getGitPrivateToken(gitPrivateTokenVo1);
                //gitPrivateToken.setScope(ri);
                //codeMapper.createUserPrivateToken(gitPrivateToken);
            //}
            return "1";
        }catch (Exception e){
            e.printStackTrace();
            return "2";
        }

    }


    /** *********************** end 用户 ***************************** **/



    /**
     * 直接获取远程的GITLIB的所有项目
     * @return
     */
    public List<GitProjectVo> getLongRangeProjects(int page, int per_page, String projectUuid, String codeName){
        String url = GITLAB_URL + "/api/v4/projects?private_token={private_token}&simple={simple}&page={page}&per_page={per_page}";
        Map<String, Object> uriVariables = new HashMap<>();
        uriVariables.put("per_page", per_page);
        uriVariables.put("page", (page-1));
        uriVariables.put("private_token", GITLAB_PRIVATE_TOKEN);
        uriVariables.put("simple", false);
        if(!"".equals(codeName) && codeName!=null){
            url+="&search={search}";
            uriVariables.put("search", codeName);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity entity = new HttpEntity<>(headers);
        ParameterizedTypeReference<List<GitProjectVo>> responseType = new ParameterizedTypeReference<List<GitProjectVo>>() {
        };
        ResponseEntity<List<GitProjectVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
        if (HttpStatus.OK == responseEntity.getStatusCode()) {
            List<GitProjectVo> gitProjectList = responseEntity.getBody();

//            Iterator<GitProjectVo> it = gitProjectList.iterator();
//            while(it.hasNext()){
//                GitProjectVo gitProjectVo = it.next();
//                int count = codeMapper.findCodeLibByProjectUuid(gitProjectVo.getCodeId(),projectUuid);
//                if(count >= 1){
//                    it.remove();
//                }
//            }
            return gitProjectList;
        }
        return null;
    }

    /**
     * 根据代码库Id查询该代码库的详细信息
     * @param codeId 代码库Id
     * @return
     */
    @Override
    public GitProjectVo getProjectsByCodeId(Long codeId) {
        try{
            String url = GITLAB_URL + "/api/v4/projects/{codeId}?private_token={privateToken}&statistics={statistics}";
            Map<String, Object> uriVariables = new HashMap<>();
            uriVariables.put("codeId", codeId);
            uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
            uriVariables.put("statistics", true);
            ResponseEntity<GitProjectVo> forEntity = restTemplate.getForEntity(url, GitProjectVo.class, uriVariables);
            if (HttpStatus.OK == forEntity.getStatusCode()) {
                GitProjectVo body = forEntity.getBody();

                GitProjectStatistics statistics = body.getStatistics();
                //获取分支数
                List<GitBranchVo> gitBranchVos = castList(getBranches(codeId, null), GitBranchVo.class);
                statistics.setBranchSize(gitBranchVos==null?0:gitBranchVos.size());
                //获取标签数
                statistics.setLabelsSize(findLabels(codeId)==null?0:findLabels(codeId).size());

                //添加访问链接
                statistics.setCommitUrl(body.getWebUrl()+"/-/commits");//提交链接
                statistics.setBranchUrl(body.getWebUrl()+"/-/branches");//分支链接
                statistics.setLabelsUrl(body.getWebUrl()+"/-/tags");//标签链接
                statistics.setStorageUrl(body.getWebUrl()+"/-/tree/"+body.getDefaultBranch());//存储单元链接
                statistics.setRepositoryUrl(body.getWebUrl()+"/-/tree/"+body.getDefaultBranch());//存储库链接

                return body;
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            e.getMessage();
            return null;
        }
    }

    /**
     * 获取代码库指定的组
     * @param codeId 代码库id
     * @param groupName 群组名称
     * @return
     */
    public List<GitGroupsVo> findGroups(Long codeId,String groupName) {
        try{
            Map<String, Object> uriVariables = new HashMap<>();
            String url = GITLAB_URL + "/api/v4/projects/{id}/groups?private_token={privateToken}&search={groupName}";
            uriVariables.put("id", codeId);
            uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
            uriVariables.put("groupName", groupName);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity entity = new HttpEntity<>(headers);
            ParameterizedTypeReference<List<GitGroupsVo>> responseType = new ParameterizedTypeReference<List<GitGroupsVo>>() {};
            ResponseEntity<List<GitGroupsVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
            if (HttpStatus.OK == responseEntity.getStatusCode()) {
                return responseEntity.getBody();
            }
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return null;

    }

    public static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<T>();
        if (obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }


    /**
     * 添加代码库
     * @param gitProjectAddVo
     * @return
     */
    public String addCodeLib(GitProjectAddVo gitProjectAddVo){
        //远程创建代码库
        try{
            //判断是否添加已有的代码库
            GitProjectVo gitProjectVo = gitLongRangeCodeLib(gitProjectAddVo);
            gitProjectVo.setProjectId(gitProjectAddVo.getProjectId());
            //根据创建成功的远程代码库，将数据添加到本地
//            if(gitProjectVo!=null){
//                GitProject gp = getGitProject(loginUser,gitProjectVo,"0");
//                codeMapper.addCodeLib(gp);
//                return gp.getUuid();
//            }
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return null;
    }

    public GitProjectVo gitLongRangeCodeLib(GitProjectAddVo gitProjectAddVo){
        String url = GITLAB_URL + "/api/v4/projects?private_token="+GITLAB_PRIVATE_TOKEN;
        // 封装参数
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        paramMap.add("name", gitProjectAddVo.getName());
        //新项目的存储库名称。如果未提供，则基于名称生成（生成为带破折号的小写）
        if(!"".equals(gitProjectAddVo.getPath()) && gitProjectAddVo.getPath()!=null){
            paramMap.add("path", gitProjectAddVo.getPath());
        }
        //新项目的命名空间（默认为当前用户的命名空间）
        if(!"".equals(gitProjectAddVo.getNamespacesid()) && gitProjectAddVo.getNamespacesid()!=null){
            paramMap.add("namespace_id", gitProjectAddVo.getNamespacesid());
        }
        //公开性
        paramMap.add("visibility", gitProjectAddVo.getVisibility());
        //简单的项目描述
        paramMap.add("description", gitProjectAddVo.getDescription());

        // 使用postForObject请求接口
        GitProjectVo gitProjectVo1 = restTemplate.postForObject(url, paramMap, GitProjectVo.class);
        return gitProjectVo1;
    }

    /**
     * 导入代码库
     * @param file
     * @param name
     * @param path
     * @param namespace
     * @param projectId
     * @return
     */
    @Override
    public Boolean importCodeBase(MultipartFile file, String name, String path, Long namespace, String projectId) {
        String url = GITLAB_URL + "/api/v4/projects/import";
        String pathName = null;
        boolean flag = false;
        try{
            //pathName = UploadFileUtils.uploadFile(file, "0");
        }catch (Exception e){
            e.printStackTrace();
        }
        //获取上传文件的全路径
        //String sPath = UploadFileUtils.getDiskByOs()+pathName;
        String sPath = "要上传的具体路径";
        File filess = new File(sPath);

        // 封装参数
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        FileSystemResource fileSystemResource = new FileSystemResource(filess);
        paramMap.add("file", fileSystemResource);
        paramMap.add("name", name);
        paramMap.add("path", path);
        paramMap.add("namespace", namespace);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.set("PRIVATE-TOKEN",GITLAB_PRIVATE_TOKEN);
        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(paramMap, headers);

        try{
            GitProjectVo gitProjectVo = restTemplate.postForObject(url, files, GitProjectVo.class);
            if(gitProjectVo!=null && !"".equals(gitProjectVo)){
                //将已导入的代码库添加到本地数据库
//                String uuid = addHaveCodeLib(gitProjectVo.getCodeId(), projectId, loginUser);
                //成功插入本地库后删除上传的文件
//                if(uuid!=null && !"".equals(uuid)){
//                    flag = UploadFileUtils.deleteFolder(sPath);
//                    return flag;
//                }
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
            return flag;
        }finally {
//            UploadFileUtils.deleteFolder(sPath);
        }
        return flag;
    }

    /**
     * 通过url导入代码库
     * @param gitProjectRepoByUrlVo
     * @return
     */
    @Override
    public String importRepoByUrlCodeBase(GitProjectRepoByUrlVo gitProjectRepoByUrlVo) {
        //LoginUser loginUser = UserAuthenticationMsg.getLoginUser();
        try{
            //判断是否添加已有的代码库
            String url = GITLAB_URL + "/api/v4/projects?private_token="+GITLAB_PRIVATE_TOKEN;
            // 封装参数
            MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
            paramMap.add("name", gitProjectRepoByUrlVo.getName());
            //新项目的存储库名称。如果未提供，则基于名称生成（生成为带破折号的小写）
            if(!"".equals(gitProjectRepoByUrlVo.getPath()) && gitProjectRepoByUrlVo.getPath()!=null){
                paramMap.add("path", gitProjectRepoByUrlVo.getPath());
            }
            //新项目的命名空间（默认为当前用户的命名空间）
            if(!"".equals(gitProjectRepoByUrlVo.getNamespaceid()) && gitProjectRepoByUrlVo.getNamespaceid()!=null){
                paramMap.add("namespace_id", gitProjectRepoByUrlVo.getNamespaceid());
            }
            //公开性
            paramMap.add("visibility", gitProjectRepoByUrlVo.getVisibility());
            //简单的项目描述
            paramMap.add("description", gitProjectRepoByUrlVo.getDescription());

            // ★★★★★ 要导入的URL地址 如果无账号密码，则默认新建
            //首先确定用户名密码是否存在
            String user_pass = "";
            String import_url = "";
            if((!"".equals(gitProjectRepoByUrlVo.getUsername()) && gitProjectRepoByUrlVo.getUsername()!=null)
                    && (!"".equals(gitProjectRepoByUrlVo.getPassword()) && gitProjectRepoByUrlVo.getPassword()!=null)){

                user_pass = gitProjectRepoByUrlVo.getUsername()+":"+gitProjectRepoByUrlVo.getPassword()+"@";
                String[] split = gitProjectRepoByUrlVo.getUrl().split("//");
                if(split.length==0){
                    return "3";
                }else{
                    import_url = split[0]+"//"+user_pass;
                    for (int i = 1; i < split.length; i++) {
                        import_url+=split[i];
                    }
                }
                paramMap.add("import_url", import_url);
            }
            paramMap.add("initialize_with_readme", true);

            //使用postForObject请求接口
            GitProjectVo gitProjectVo = restTemplate.postForObject(url, paramMap, GitProjectVo.class);

            //根据创建成功的远程代码库，将数据添加到本地
            /*if(gitProjectVo!=null){
                gitProjectVo.setProjectId(gitProjectRepoByUrlVo.getProjectId());
                GitProject gp = getGitProject(loginUser,gitProjectVo,"0");
                codeMapper.addCodeLib(gp);
                return "1";
            }*/
            return "1";
        }catch (Exception e){
            e.printStackTrace();
            return "2";
        }

    }


    /**
     * 编辑代码库
     * @param gitProjectAddVo
     * @return
     */
    @Override
    public String editCodeBase(GitProjectAddVo gitProjectAddVo) {
        //LoginUser loginUser = UserAuthenticationMsg.getLoginUser();
        String url = GITLAB_URL + "/api/v4/projects/"+gitProjectAddVo.getCodeId()+"?private_token="+GITLAB_PRIVATE_TOKEN;
        gitProjectAddVo.setPath(gitProjectAddVo.getName());
        try{
            //设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity httpEntity = new HttpEntity<>(gitProjectAddVo, headers);
            ResponseEntity<GitProjectVo> resEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, GitProjectVo.class);

            if (HttpStatus.OK == resEntity.getStatusCode()) {
                GitProjectVo body = resEntity.getBody();
                if(body!=null){
                    /*int i = codeMapper.editCodeBase(body);
                    if(i>0){
                        return "yes";
                    }*/
                    return "yes";
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return "no";
        }
        return "no";
    }

    /**
     * 删除代码库
     * @param codeId 代码库id
     * @param projectId 项目id
     * @return
     */
    @Override
    public void deleteCodeLib(Long codeId,String projectId) {
        //1、先查询是否存在，不存在就不进行远程调用删除
        GitProjectVo gitProjectVo = getProjectsByCodeId(codeId);
        if(gitProjectVo!=null){
            Map<String, Object> uriVariables = new HashMap<>();
            String url = GITLAB_URL + "/api/v4/projects/{codeId}?private_token={privateToken}";
            uriVariables.put("codeId", codeId);
            uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
            ///2、先删除gitLab代码库上面的
            restTemplate.delete(url,uriVariables);
        }
        //3、删除本地数据库的记录
        //codeMapper.deleteCodeLib(codeId,projectId);
    }

    /**
     * 根据id或者名称搜索群组
     * @param id 空间id
     * @return
     */
    @Override
    public Object findGroups(Long id, int page,int per_page,String isPage) {
        Map<String, Object> uriVariables = new HashMap<>();
        String url = GITLAB_URL + "/api/v4/groups";
        String url_prl="?private_token={privateToken}";
        uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
        if(id!=null){
            url+="/{id}"+url_prl;
            uriVariables.put("id", id);
            ResponseEntity<GitGroupsVo> forEntity = restTemplate.getForEntity(url, GitGroupsVo.class, uriVariables);
            if (HttpStatus.OK == forEntity.getStatusCode()) {
                return forEntity.getBody();
            }
        }else{
            if("YES".equals(isPage)){
                url+= url_prl+"&page={page}&per_page={per_page}";
                uriVariables.put("per_page", per_page);
                uriVariables.put("page", (page-1));
            }else{
                url+= url_prl+"&per_page={per_page}";
                uriVariables.put("per_page", "100");
            }
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity entity = new HttpEntity<>(headers);
            ParameterizedTypeReference<List<GitGroupsVo>> responseType = new ParameterizedTypeReference<List<GitGroupsVo>>() {};
            ResponseEntity<List<GitGroupsVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
            if (HttpStatus.OK == responseEntity.getStatusCode()) {
                List<GitGroupsVo> body = responseEntity.getBody();
                for (int i = 0; i < body.size(); i++) {
                    GitGroupsVo gitGroupsVo = body.get(i);
                    gitGroupsVo.setKind("group");
                }
                //对群组进行倒叙排列
                body.sort(Comparator.comparing(GitGroupsVo::getCreated_at).reversed());

                GitGroupsVo groups = new GitGroupsVo();
                GitAuthorVo newUser = findNewUser();
                groups.setId(newUser.getId()).setName(newUser.getUsername()).setPath(newUser.getUsername()).setKind("user");
                body.add(groups);

                return body;
            }
        }
        return null;
    }


    /**
     * 获取当前用户
     * @return
     */
    public GitAuthorVo findNewUser() {
        Map<String, Object> uriVariables = new HashMap<>();
        String url = GITLAB_URL + "/api/v4/user?private_token={privateToken}";
        uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
        ResponseEntity<GitAuthorVo> forEntity = restTemplate.getForEntity(url, GitAuthorVo.class, uriVariables);
        if (HttpStatus.OK == forEntity.getStatusCode()) {
            return forEntity.getBody();
        }
        return null;
    }



    /**
     * 添加群组
     * @param gitGroupsVo
     * @return
     */
    @Override
    public String addGroups(GitGroupsVo gitGroupsVo) {
        try{
            //1、添加群组前先查询群组是否存在，存在不然添加
            List<GitGroups> groups = findGroups(gitGroupsVo.getName());
            if(groups.size()>0){
                return "3";
            }else{
                String url = GITLAB_URL + "/api/v4/groups?private_token="+GITLAB_PRIVATE_TOKEN;
                // 封装参数
                MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
                paramMap.add("name", gitGroupsVo.getName());
                //新群组的存储库名称。默认跟随name一样
                paramMap.add("path", gitGroupsVo.getName());
                //公开性
                paramMap.add("visibility", gitGroupsVo.getVisibility());
                //简单的项目描述
                paramMap.add("description", gitGroupsVo.getDescription());
                // 使用postForObject请求接口
                GitGroups gitGroups1 = restTemplate.postForObject(url, paramMap, GitGroups.class);
                return "1";
            }
        }catch (Exception e){
            e.printStackTrace();
            return "2";
        }

    }

    /**
     * 查询群组是否存在
     * @param groupsName
     * @return
     */
    public List<GitGroups> findGroups(String groupsName) {
        String url = GITLAB_URL + "/api/v4/groups?search={search}&private_token="+GITLAB_PRIVATE_TOKEN;
        // 封装参数
        Map<String, Object> uriVariables = new HashMap<>();
        uriVariables.put("search", groupsName);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity entity = new HttpEntity<>(headers);
        ParameterizedTypeReference<List<GitGroups>> responseType = new ParameterizedTypeReference<List<GitGroups>>() {};
        ResponseEntity<List<GitGroups>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
        if (HttpStatus.OK == responseEntity.getStatusCode()) {
            return responseEntity.getBody();
        }
        return null;
    }
    /**
     * 导入群组
     * @param file 文件
     * @param name 要导入的群组的名称。如果未提供，则默认为项目路径
     * @param path 新群组的名称和路径
     * @return
     */
    @Override
    public Boolean importGroups(MultipartFile file, String name, String path) {
        //LoginUser loginUser = UserAuthenticationMsg.getLoginUser();
        String url = GITLAB_URL + "/api/v4/groups/import";
        String pathName = null;
        boolean flag = false;
        try{
            //pathName = UploadFileUtils.uploadFile(file, "0");
        }catch (Exception e){
            e.printStackTrace();
        }
        //获取上传文件的全路径
        //String sPath = UploadFileUtils.getDiskByOs()+pathName;
        String sPath = "实际上传的地址";
        File filess = new File(sPath);

        // 封装参数
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        FileSystemResource fileSystemResource = new FileSystemResource(filess);
        paramMap.add("file", fileSystemResource);
        paramMap.add("name", name);
        paramMap.add("path", path);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.set("PRIVATE-TOKEN",GITLAB_PRIVATE_TOKEN);
        HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(paramMap, headers);

        try{
            GitGroups gitGroups = restTemplate.postForObject(url, files, GitGroups.class);
            //删除上传的文件
            if(gitGroups!=null && !"".equals(gitGroups)){
                //flag = UploadFileUtils.deleteFolder(sPath);
                return true;
            }
        }catch (Exception e){
            e.printStackTrace();
            return flag;
        }finally {
            //UploadFileUtils.deleteFolder(sPath);
        }
        return flag;
    }

    /**
     * 编辑群组
     * @param gitGroupsVo
     * @return
     */
    @Override
    public String editGroups(GitGroupsVo gitGroupsVo) {
        //LoginUser loginUser = UserAuthenticationMsg.getLoginUser();
        String url = GITLAB_URL + "/api/v4/groups/"+gitGroupsVo.getId()+"?private_token="+GITLAB_PRIVATE_TOKEN;
        gitGroupsVo.setPath(gitGroupsVo.getName());
        try{
            //设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity httpEntity = new HttpEntity<>(gitGroupsVo, headers);
            ResponseEntity<GitGroupsVo> resEntity = restTemplate.exchange(url, HttpMethod.PUT, httpEntity, GitGroupsVo.class);

            if (HttpStatus.OK == resEntity.getStatusCode()) {
                GitGroupsVo body = resEntity.getBody();
                if(body!=null){
                    return "yes";
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return "no";
        }
        return "no";
    }

    /**
     * 删除群组 gitLab默认延迟删除 7天，现已经改为立即删除
     * @param groupsId
     * @return
     */
    @Override
    public String deleteGroups(Long groupsId) {
        //1、先查询该组关联的代码库
        //LoginUser loginUser = UserAuthenticationMsg.getLoginUser();
        List<GitProjectVo> list = findCodeByGroupsId(1, 100, groupsId, "1");
        //2、删除群组
        Map<String, Object> uriVariables = new HashMap<>();
        String url = GITLAB_URL + "/api/v4/groups/{groupsId}?private_token={privateToken}";
        uriVariables.put("groupsId", groupsId);
        uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
        //1、先删除gitLab代码库上面的
        ResponseEntity<Map> resultEntity = restTemplate.exchange(url, HttpMethod.DELETE, null,Map.class, uriVariables);
        if(resultEntity != null){
            if(resultEntity.getStatusCodeValue()==202){
                for (int i = 0; i < list.size(); i++) {
                    //3、如果群组删除成功则删除代码库
                    deleteCodeLib(list.get(i).getCodeId(),null);
                }
                return "yes";
            }else{
                return "no";
            }
        }else {
            return "no";
        }
    }
    /**
     * 根据群组获取群组的代码库
     * @param page
     * @param per_page
     * @param groupsId
     * @return
     */
    @Override
    public List<GitProjectVo> findCodeByGroupsId(int page, int per_page, Long groupsId,String flag) {
        String url = GITLAB_URL + "/api/v4/groups/"+groupsId+"/projects?private_token={private_token}&page={page}&per_page={per_page}";
        Map<String, Object> uriVariables = new HashMap<>();
        uriVariables.put("private_token", GITLAB_PRIVATE_TOKEN);
        uriVariables.put("page", (page-1));
        uriVariables.put("per_page", per_page);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity entity = new HttpEntity<>(headers);
        ParameterizedTypeReference<List<GitProjectVo>> responseType = new ParameterizedTypeReference<List<GitProjectVo>>() {};
        ResponseEntity<List<GitProjectVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
        if (HttpStatus.OK == responseEntity.getStatusCode()) {
            if("0".equals(flag)){
                ArrayList list = new ArrayList();
                if(responseEntity.getBody().size()>0){
                    for (GitProjectVo gpv:responseEntity.getBody()) {
                        GitProject gitProject = getGitProject(gpv, "1");
                        List<GitMergeVo> MergeList = getMerge(gitProject.getCodeId(), "opened");
                        gitProject.setMergeCount(MergeList.size());
                        list.add(gitProject);
                    }
                }
                return list;
            }else{
                return responseEntity.getBody();
            }
        }
        return null;
    }


    /**
     * 根据代码库id和状态获取合并请求
     * @param codeId 代码库id
     * @param state  ( opened、closed、 或merged) 或所有状态 ( ) 的合并请求all
     * @return
     */
    public List<GitMergeVo> getMerge(Long codeId,String state) {
        Map<String, Object> uriVariables = new HashMap<>();
        String url = GITLAB_URL + "/api/v4/projects/{codeId}/merge_requests?private_token={privateToken}&state={state}";
        uriVariables.put("codeId", codeId);
        uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
        uriVariables.put("state", state);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity entity = new HttpEntity<>(headers);
        ParameterizedTypeReference<List<GitMergeVo>> responseType = new ParameterizedTypeReference<List<GitMergeVo>>() {};
        ResponseEntity<List<GitMergeVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
        if (HttpStatus.OK == responseEntity.getStatusCode()) {
            List<GitMergeVo> body = responseEntity.getBody();
            for (int i = 0; i < body.size(); i++) {
                GitMergeVo gitMergeVo = body.get(i);
                gitMergeVo.setCreatedTime(getDateStrFromISO8601Timestamp(gitMergeVo.getCreated_at()));
                gitMergeVo.setUpdatedTime(getDateStrFromISO8601Timestamp(gitMergeVo.getUpdated_at()));
            }
            return body;
        }
        return null;
    }


    /**
     * 根据代码库id，获取分支，也可获取该代码库的单个分支
     * @param codeId
     * @param branchName
     * @return
     */
    public Object getBranches(Long codeId,String branchName) {
        Map<String, Object> uriVariables = new HashMap<>();
        String url = "";
        if("".equals(branchName) || branchName == null){
            url = GITLAB_URL + "/api/v4/projects/{codeId}/repository/branches?private_token={privateToken}";
        }else{
            url = GITLAB_URL + "/api/v4/projects/{codeId}/repository/branches/{branch}?private_token={privateToken}";
            uriVariables.put("branch", branchName);
        }
        uriVariables.put("codeId", codeId);
        uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
        try{
            if("".equals(branchName) || branchName == null){
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);

                HttpEntity entity = new HttpEntity<>(headers);
                ParameterizedTypeReference<List<GitBranchVo>> responseType = new ParameterizedTypeReference<List<GitBranchVo>>() {
                };
                ResponseEntity<List<GitBranchVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
                if (HttpStatus.OK == responseEntity.getStatusCode()) {
                    return responseEntity.getBody();
                }
            }else{
                ResponseEntity<GitBranchVo> forEntity = restTemplate.getForEntity(url, GitBranchVo.class, uriVariables);
                if (HttpStatus.OK == forEntity.getStatusCode()) {
                    return forEntity.getBody();
                }
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 添加分支
     * @param gitBranchAddVo
     * @return
     */
    @Override
    public GitBranchVo addBranches(GitBranchAddVo gitBranchAddVo) {
        //1、添加分支前先查询分支是否存在，存在不添加
        Object branches = getBranches(gitBranchAddVo.getCodeId(), gitBranchAddVo.getBranch());
        if(!"".equals(branches) && branches != null){
            return null;
        }else{
            try{
                String url = GITLAB_URL + "/api/v4/projects/{id}/repository/branches?private_token={privateToken}&branch={branch}&ref={ref}";
                Map<String, Object> uriVariables = new HashMap<>();
                uriVariables.put("id", gitBranchAddVo.getCodeId());
                uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
                uriVariables.put("branch", gitBranchAddVo.getBranch());
                uriVariables.put("ref", gitBranchAddVo.getRef());
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);

                HttpEntity entity = new HttpEntity<>(headers);
                ParameterizedTypeReference<GitBranchVo> responseType = new ParameterizedTypeReference<GitBranchVo>() {
                };
                ResponseEntity<GitBranchVo> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, responseType, uriVariables);
                if (HttpStatus.CREATED == responseEntity.getStatusCode()) {
                    return responseEntity.getBody();
                }
            }catch (Exception e){
                e.printStackTrace();
                return null;
            }
            return null;
        }
    }


    /**
     * 根据项目及分支获取提交记录 每次能查询20条记录
     * @param codeId 代码库id
     * @param branchName 分支名称
     * @param page 页 从1开始
     * @return
     */
    @Override
    public List<GitBranchCommitVo> getBranchesCommits(Long codeId, String branchName, int page, int per_page) throws Exception {
        try{
            String url = GITLAB_URL + "/api/v4/projects/{codeId}/repository/commits?private_token={private_token}&ref_name={ref_name}&page={page}&per_page={per_page}";
            Map<String, Object> uriVariables = new HashMap<>();
            uriVariables.put("codeId", codeId);
            uriVariables.put("private_token", GITLAB_PRIVATE_TOKEN);
            uriVariables.put("ref_name", branchName);
            uriVariables.put("page", (page-1));
            uriVariables.put("per_page", per_page);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity entity = new HttpEntity<>(headers);
            ParameterizedTypeReference<List<GitBranchCommitVo>> responseType = new ParameterizedTypeReference<List<GitBranchCommitVo>>() {
            };
            ResponseEntity<List<GitBranchCommitVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
            if (HttpStatus.OK == responseEntity.getStatusCode()) {
                return responseEntity.getBody();
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 根据代码库查询标签
     * @param codeId 空间id
     * @return
     */
    public List<GitTagsVo> findLabels(Long codeId) {
        Map<String, Object> uriVariables = new HashMap<>();
        String url = GITLAB_URL + "/api/v4/projects/{codeId}/repository/tags?private_token={privateToken}&per_page={per_page}";
        uriVariables.put("codeId", codeId);
        uriVariables.put("privateToken", GITLAB_PRIVATE_TOKEN);
        uriVariables.put("per_page", 100);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity entity = new HttpEntity<>(headers);
        ParameterizedTypeReference<List<GitTagsVo>> responseType = new ParameterizedTypeReference<List<GitTagsVo>>() {};
        ResponseEntity<List<GitTagsVo>> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, responseType, uriVariables);
        if (HttpStatus.OK == responseEntity.getStatusCode()) {
            return responseEntity.getBody();
        }
        return null;
    }

    /**
     * 转换获取Contents
     */
    private GitProject getGitProject(GitProjectVo vo,String flag) {
        GitProject gp = new GitProject();
        BeanUtils.copyProperties(vo, gp);
        if("0".equals(flag)){
            //main：使用 GitLab 14.0 或更高版本创建的项目。
            //master：在 GitLab 14.0 之前创建的项目。
            gp.setDefaultBranch("main");
            if (Utils.isEmpty(gp.getUuid())){
                gp.setUuid(getUUID());
            }
        }
        return gp;
    }

    /**
     * 转换获取Contents
     */
    private GitUser getGitUser(GitUserVo vo) {
        GitUser user = new GitUser();
        BeanUtils.copyProperties(vo, user);
        user.setIsDelete("0");
        if (Utils.isEmpty(user.getUuid())){
            user.setUuid(getUUID());
        }
        return user;
    }

    /**
     * 转换获取Contents
     */
    private GitPrivateToken getGitPrivateToken(GitPrivateTokenVo vo) {
        GitPrivateToken token = new GitPrivateToken();
        BeanUtils.copyProperties(vo, token);
        if (Utils.isEmpty(token.getUuid())){
            token.setUuid(getUUID());
        }
        return token;
    }
    /**
     * 将YYYY-MM-dd HH:mm:ss转为ISO8601的YYYY-MM-dd'T'HH:mm:ss'Z'
     * @param time
     * @return
     * @throws Exception
     */
    public String timeTrim(String time) throws Exception {
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = ft.parse(time);

        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        df.setTimeZone(tz);
        String nowAsISO = df.format(date);
        System.out.println(nowAsISO);
        return nowAsISO;
    }

    /**
     * 传入String类型日期(ISO8601标准时间:yyyy-MM-dd'T'HH:mm:ss.SSS'Z')，返回字符串类型时间(yyyy-MM-dd HH:mm:ss)
     * @param ISOdate
     * @return
     */
    public static String getDateStrFromISO8601Timestamp(String ISOdate){
        DateTimeFormatter dtf1 = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        DateTime dt= dtf1.parseDateTime(ISOdate);
        DateTimeFormatter dtf2= DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        return dt.toString(dtf2);
    }

    public static String getUUID() {
        return replaceUUID(UUID.randomUUID());
    }

    public static String replaceUUID(Object uuid) {
        return uuid.toString().replaceAll("\\-", "");
    }

}
